package org.infodavid.common.persistence.impl;

import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;

import org.infodavid.common.persistence.exceptions.ConcurrentModificationException;
import org.infodavid.common.persistence.exceptions.IErrorHandler;

/**
 * The Class JpaErrorHandler.
 */
public class HibernateErrorHandler implements IErrorHandler<PersistenceException> {

	/**
	 * Checks if is concurrent modification exception.
	 * @param error the error
	 * @return true, if is concurrent modification exception
	 */
	private boolean isConcurrentModificationException(final Throwable error) {
		boolean concurrent = false;
		Throwable item = error;

		while (item != null && !concurrent) {
			concurrent = item instanceof OptimisticLockException;

			if (item.getCause() == item) {
				item = null;
			}
			else {
				item = item.getCause();
			}
		}

		return concurrent;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.persistence.exceptions.IErrorHandler#handle(java.lang.Class,
	 * java.lang.Object, java.lang.Throwable)
	 */
	@SuppressWarnings("rawtypes")
	public boolean handle(final Class type, final Object id, final Throwable error)
	    throws PersistenceException {
		if (isConcurrentModificationException(error)) {
			throw new ConcurrentModificationException(type, id);
		}

		if (error instanceof PersistenceException) {
			throw (PersistenceException)error;
		}

		throw new PersistenceException("An error occurs while accessing data: " + type + " (" + id
		    + ')', error);
	}
}
